﻿using ServiceStack.Redis;
using System;

namespace ERefCommon
{
    /// <summary>
    /// redis 工具
    /// </summary>
    public static class RedisTool
    {
        /// <summary>
        /// redis
        /// </summary>
        private static RedisClient _redis = null;
        /// <summary>
        /// 设置redis
        /// </summary>
        /// <param name="host">主机</param>
        /// <param name="port">端口</param>
        /// <param name="password">口令</param>
        /// <returns>redis客户端</returns>
        public static RedisClient SetRedisClient(string host = "localhost", int port = 6379, string password = null)
        {
            if (_redis == null)
            {
                _redis=new RedisClient(host, port, password);
            }
            return _redis;
        }

        /// <summary>
        /// 重置redis
        /// </summary>
        /// <param name="host">主机</param>
        /// <param name="port">端口</param>
        /// <param name="password">口令</param>
        /// <returns>redis客户端</returns>
        public static RedisClient ReSetRedisClient(string host = "localhost", int port = 6379, string password = null)
        {
            if (_redis!=null)
            {
                _redis.Dispose();
            }
            _redis=new RedisClient(host, port, password);
            return _redis;
        }
        /// <summary>
        /// 判定键是否存在
        /// </summary>
        /// <param name="redis">redis实体</param>
        /// <param name="key">键</param>
        /// <returns>判定结果</returns>
        /// <exception cref="Exception">redis未配置</exception>
        public static bool ExistKey(this RedisClient redis, string key)
        {
            if (redis==null)
            {
                throw new Exception("redis未配置");
            }
            return redis.Exists(key)>0;
        }

        /// <summary>
        /// 判定键是否存在
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>判定结果</returns>
        public static bool ExistKey(string key)
        {
            return ExistKey(_redis, key);
        }
        /// <summary>
        /// 添加键值对
        /// </summary>
        /// <param name="redis">redis实例</param>
        /// <param name="key">键</param>
        /// <param name="val">值</param>
        /// <param name="expireSeconds">过期秒数，小于0则不限制</param>
        public static void AddValue(this RedisClient redis, string key, string val, int expireSeconds = 0)
        {
            if (redis==null)
            {
                return;
            }
            if (expireSeconds<=0)
            {
                redis.SetEntry(key, val);
            }
            else
            {
                redis.SetEntry(key, val, TimeSpan.FromSeconds(expireSeconds));
            }
        }
        /// <summary>
        /// 添加键值对
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="val">值</param>
        /// <param name="expireSeconds">过期秒数，小于0则不限制</param>
        public static void AddValue(string key, string val, int expireSeconds = 0)
        {
            AddValue(_redis, key, val, expireSeconds);
        }

        /// <summary>
        /// 获取键值
        /// </summary>
        /// <param name="redis">redis实例</param>
        /// <param name="key">键</param>
        /// <returns>值</returns>
        /// <exception cref="Exception">键对应值不存在</exception>
        public static string GetValue(this RedisClient redis, string key)
        {
            if (redis==null)
            {
                throw new Exception("redis未配置");
            }
            if (redis.Exists(key)>0)
            {
                string res = redis.GetValue(key);
                if (res==null||string.IsNullOrEmpty(res.Trim()))
                {
                    throw new Exception("空值或已过期");
                }
                return res;
            }
            else
            {
                throw new Exception("未发现该键对应的存储");
            }
        }

        /// <summary>
        /// 获取键值
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>值</returns>
        public static string GetValue(string key)
        {
            return GetValue(_redis, key);
        }
    }
}
